package main

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type Student struct {
	ID     int    `json:"id"`
	Name   string `json:"name"`
	Gender string `json:"gender"`
	Sno    string `json:"sno"`
}

func (s Student) GetName() {
	fmt.Println(s.Name)
}

func (s Student) GetId() {
	fmt.Println(s.ID)
}

func (s *Student) SetInfo(name string, gender string) {
	s.Name = name
	s.Gender = gender
}

func reflectFn(a interface{}) {
	v := reflect.TypeOf(a)
	v2 := reflect.ValueOf(a)
	fmt.Println(v, v.Kind())
	value, ok := v.FieldByName("ID")
	if ok {
		fmt.Printf("xxxxxx %v \n", value.Tag)
	}
	fmt.Println(v2, v2.FieldByName("Name"))
}
func reflectFn2(a interface{}) {
	v := reflect.TypeOf(a)
	v2 := reflect.ValueOf(a)
	fmt.Println(v, v.Kind())
	fmt.Println(v2, v2.Elem().FieldByName("Name"))
}

func SetReflectValue(v interface{}) {
	v1 := reflect.ValueOf(v)
	typeStr := v1.Elem().Kind()

	if typeStr == reflect.String {
		v1.Elem().SetString("结束吧 累了")
	}

}

func PrintStructFn(s interface{}) {
	t := reflect.TypeOf(s)
	v1 := reflect.ValueOf(s)
	if t.Kind() != reflect.Struct && t.Elem().Kind() != reflect.Struct {
		fmt.Println("参数不是结构体")
		return
	}

	m, _ := t.MethodByName("GetName")
	fmt.Println(m)
	fmt.Println("-------------------------------------------")
	m2 := t.NumMethod()
	for v := range m2 {
		fmt.Println(t.Method(v))
	}
	fmt.Println("-------------------------------------------")
	fmt.Println(s)
	var params = []reflect.Value{
		reflect.ValueOf("小H"),
		reflect.ValueOf("女2"),
	}
	//params = append(params, reflect.ValueOf("小了"))
	//params = append(params, reflect.ValueOf("女"))
	v1.MethodByName("SetInfo").Call(params)
	fmt.Println(s)

}

func main() {
	s1 := Student{
		ID:     1,
		Name:   "李四",
		Gender: "男",
		Sno:    "001",
	}
	var s, _ = json.Marshal(s1)
	jsonStr := string(s)
	fmt.Println(jsonStr)

	reflectFn(s1)
	reflectFn2(&s1)

	var p = "hello word"

	SetReflectValue(&p)
	fmt.Println(p)

	PrintStructFn(&s1)
}
